﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Threading;

namespace AskPingConsole
{

    class Program
    {
        static private int iLine = 0;
        static private List<string> pinglist = new List<string>();
        static private ConsoleColor OldColor;

        static void Main(string[] args)
        {
            OldColor = Console.ForegroundColor;
            string HostNameStr = Dns.GetHostName();
            IPHostEntry ipHost = Dns.Resolve(HostNameStr);
            string HostDNSNameStr = ipHost.HostName;
            //string userStr = Net.UserName;
            string userStr = System.Environment.UserName;

            if (IsOffline())
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("No internet connection detected.");
                Console.WriteLine("Press any key to exit.");
                Console.ReadLine();
                Console.ForegroundColor = OldColor;
                return;
            }

            PrintLine("HostName - " + HostDNSNameStr // HostNameStr
                + " ; MachineName - " + System.Environment.MachineName);
            //    + " ; DNS name = " + HostDNSNameStr);
            PrintLine("Platform - " + System.Environment.OSVersion.Platform
                + " ; SP - " + System.Environment.OSVersion.ServicePack
                + " ; OSVersion - " + System.Environment.OSVersion.Version);
            PrintLine("User - " + userStr +
                " ; Domain - " + System.Environment.UserDomainName);
            PrintIPAddress(ipHost);
            PrintProxy();
            PrintLine("_________________________________________");
            PrintAdapters();
            PrintLine("_________________________________________");

            pinglist.Add("192.168.15.251");
            pinglist.Add("mail.askona.ru");
            pinglist.Add("sps.askona.ru");
            pinglist.Add("s1011");
            pinglist.Add("askona.ru");
            pinglist.Add("2.askona.ru");
            pinglist.Add("3.askona.ru");

            foreach(string s in pinglist)
                Ping(s, 3);

            Console.ForegroundColor = ConsoleColor.Green;
            PrintLine("");
            PrintLine("================= The End ==================");
            PrintLine("Application process stoped... Press any key.");
            Console.ReadKey();
            Console.ForegroundColor = OldColor;

        }

        [Flags]
        enum ConnectionState : int
        {
            INTERNET_CONNECTION_MODEM = 0x1,
            INTERNET_CONNECTION_LAN = 0x2,
            INTERNET_CONNECTION_PROXY = 0x4,
            INTERNET_RAS_INSTALLED = 0x10,
            INTERNET_CONNECTION_OFFLINE = 0x20,
            INTERNET_CONNECTION_CONFIGURED = 0x40
        }

        [DllImport("wininet", CharSet = CharSet.Auto)]
        static extern bool InternetGetConnectedState(ref ConnectionState lpdwFlags, int dwReserved);

        static void Ping(string host, int count)
        {
            int received = 0;
            bool bError = false;
            string LastErrorStr = "";
            Console.Write("+++ : " 
                + host.PadRight(18)
                + " -");
            for (int i = 0; i < count; i++)
            {
                Print(".");
                IPAddress[] ip;
                try
                {
                    ip = Dns.GetHostAddresses(host);
                }
                catch (System.Net.Sockets.SocketException ex)
                {
                    bError = true;
                    LastErrorStr = ex.Message;
                    break;
                }
                PingOptions options = new PingOptions(128, true);
                Ping ping = new Ping();
                byte[] data = new byte[32];
                List<long> responseTimes = new List<long>();
                PingReply reply = ping.Send(ip[0], 1000, data, options);
                if (reply != null)
                {
                    switch (reply.Status)
                    {
                        case IPStatus.Success:
                            //Console.WriteLine("Reply from {0}: bytes={1} time={2}ms TTL={3}",
                            //    reply.Address, reply.Buffer.Length
                            //    , reply.RoundtripTime, reply.Options.Ttl);
                            received++;
                            //responseTimes.Add(reply.RoundtripTime);
                            break;
                        case IPStatus.TimedOut:
                            LastErrorStr = "Request timed out.";
                            continue;
                        default:
                            bError = true;
                            LastErrorStr =
                                String.Format(
                                    "Ping failed {0}", reply.Status.ToString());
                            break;
                    }
                }
                else
                {
                    bError = true;
                    LastErrorStr = "Ping failed for an unknown reason";
                }
            }
            if (bError)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("Error - " + LastErrorStr);
                Console.ForegroundColor = OldColor;
            }
            else
            {
                if (received == 0)
                    Console.ForegroundColor = ConsoleColor.Red;
                else if (received != count)
                    Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Write(@" {0} = [ OK-{1} \ Bad-{2} ]"
                    , received, received, count - received);
            }
            Console.ForegroundColor = OldColor;
            Console.WriteLine("");
        }
        static void PrintProxy()
        {
            IWebProxy proxy = GlobalProxySelection.Select;
            if (proxy != null)
            {
                PrintLine("Proxy - " +
                    ((System.Net.WebProxy)(proxy)).Address);
            }
        }
        static void PrintAdapters()
        {
            ManagementObjectSearcher query = new
                ManagementObjectSearcher(
                    "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
            ManagementObjectCollection queryCollection = query.Get();
            foreach (ManagementObject mo in queryCollection)
            {
                int i = -1;
                string[] addresses = (string[])mo["IPAddress"];
                string[] subnets = (string[])mo["IPSubnet"];
                string[] defaultgateways = (string[])mo["DefaultIPGateway"];
                string[] DNS = (string[])mo["DNSServerSearchOrder"];
                string DNSStr = "    DNS:        : ";

                Console.WriteLine("");
                Console.Write("Network Card: ");
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine(mo["Description"]);
                Console.ForegroundColor = OldColor;
                //Console.WriteLine("    MAC Address: {0}", mo["MACAddress"]);

                /*
                foreach (string ipaddress in addresses)
                {
                    Console.WriteLine("    IP Address: {0}", ipaddress);
                }
                foreach (string subnet in subnets)
                {
                    Console.WriteLine("    Subnet Mask: {0}", subnet);
                }
                foreach (string defaultgateway in defaultgateways)
                {
                    Console.WriteLine("    Gateway: {0}", defaultgateway);
                }
                */

                string ipaddress = addresses[0];
                string defaultgateway = "";
                if (defaultgateways!=null)
                {
                    defaultgateway = defaultgateways[0];
                    pinglist.Add(defaultgateway);
                }
                string subnet = subnets[0];
                Console.WriteLine("    ServiceName : {0}", mo["ServiceName"]);
                Console.WriteLine("    MAC         : {0}", mo["MACAddress"]);
                Console.WriteLine("    IP Address  : {0}", ipaddress);
                Console.WriteLine("    Gateway     : {0}", defaultgateway);
                Console.WriteLine("    Subnet Mask : {0}", subnet);
                if (DNS != null)
                {
                    i = -1;
                    foreach (string s in DNS)
                    {
                        i++; if (i > 0) DNSStr += " ; ";
                        DNSStr += s;
                        pinglist.Add(s);
                    }
                    Console.WriteLine(DNSStr);
                }

                Console.WriteLine(". . . . . . . . . . . . . . . . . . . . . .");
            }
        }
        static void PrintAdapters2()
        {
            using (ManagementObjectSearcher searcher =
                new ManagementObjectSearcher(
                    "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'"))
            {
                foreach (ManagementObject mo in searcher.Get())
                {
                    try
                    {
                        string ipStr = (mo["IPAddress"] == null)
                                ? "" : (mo["IPAddress"] as string[])[0];

                        if (!String.IsNullOrEmpty(ipStr))
                        {
                            string caption = mo["Caption"].ToString();
                            if (caption.Length > 25)
                                caption = caption.Substring(0, 25);

                            Console.WriteLine(
                                 "; IP: {0}"
                                + "; MAC: {1}"
                                + "; Name: {2}"
                                , ipStr
                                , mo["MACAddress"]
                                , caption
                                );
                        }
                    }
                    finally
                    {
                        mo.Dispose();
                    }
                }
            }
        }
        static void PrintIPAddress(IPHostEntry ipHost)
        {
            string ipAddressStr = "";
            List<string> ipAddress = new List<string>();
            int i = -1;
            foreach (IPAddress ipaddr in ipHost.AddressList)
            {
                ipAddress.Add(ipaddr.ToString());
                i++; if (i > 0) ipAddressStr += " ; ";
                ipAddressStr += ipaddr.ToString();
            }
            PrintLine("IP address - " + ipAddressStr);
        }
        static void Print(string str)
        {
            Console.Write(str);
        }
        static void PrintLine(string str)
        {
            iLine++;
            Console.WriteLine(iLine.ToString() + ". " + str);
        }

        static bool IsOffline()
        {
            ConnectionState state = 0;
            InternetGetConnectedState(ref state, 0);
            if (((int)ConnectionState.INTERNET_CONNECTION_OFFLINE & (int)state) != 0)
            {
                return true;
            }

            return false;
        }

        public class Net
        {

            protected static String _HostName = System.Net.Dns.GetHostName();
            public static String HostName
            {
                get { return _HostName; }
            }

            public static string UserName
            {
                get
                {
                    System.Security.Principal.WindowsPrincipal p =
                        System.Threading.Thread.CurrentPrincipal
                            as System.Security.Principal.WindowsPrincipal;
                    if (p == null)
                        return "";
                    return p.Identity.Name;
                }
            }

        }
    }
}
